package com.liuyu.common.framework.rocketmq.status.notify.context;

import com.liuyu.common.framework.queue.model.QueueMessageWrapper;
import com.liuyu.common.framework.rocketmq.status.notify.service.EventMessageProcessStatus;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 消息通知
 * @author: liuyu
 * @date: 2022/6/27 12:05
 * @version: 1
 */
@Service
public class EventMessageProcessStatusContext implements InitializingBean {
    private Map<String, EventMessageProcessStatus> map = new ConcurrentHashMap<>();
    @Autowired
    private List<EventMessageProcessStatus> strategies;

    public static final int MAX_TRY_TIMES = 3;


    /**
     * Invoked by the containing {@code BeanFactory} after it has set all bean properties
     * and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.
     * <p>This method allows the bean instance to perform validation of its overall
     * configuration and final initialization when all bean properties have been set.
     * @throws Exception in the event of misconfiguration (such as failure to set an
     * essential property) or if initialization fails for any other reason
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        for (EventMessageProcessStatus strategy : strategies) {
            for (String topicTag : strategy.getTopicTags()) {
                map.put(topicTag, strategy);
            }
        }
    }


    /**
     * 执行本地方法
     * @author liuyu
     * @date 2022/4/9 21:57
     * @param queueMessageWrapper
     * @return boolean
     */
    public <T> void processQueueMessage(QueueMessageWrapper<T> queueMessageWrapper) {
        EventMessageProcessStatus strategy = getEventMessageProcessStatus(queueMessageWrapper.getTag(), queueMessageWrapper.getTopic());
        if (strategy != null) {
            strategy.processQueueMessage(queueMessageWrapper);
        }
    }


    /**
     * 保存失败的消息
     * @author liuyu
     * @date 2021/8/17 10:45
     * @param queueMessageWrapper    包装类
     * @param exception 异常
     * @return boolean
     */
    public <T, V> boolean saveFailMessage(QueueMessageWrapper<T> queueMessageWrapper, Exception exception) {
        EventMessageProcessStatus strategy = getEventMessageProcessStatus(queueMessageWrapper.getTag(), queueMessageWrapper.getTopic());
        if (strategy != null) {
            return strategy.saveFailMessage(queueMessageWrapper, exception);
        } else {
            return false;
        }
    }

    private EventMessageProcessStatus getEventMessageProcessStatus(String tag2, String topic) {
        String tag = getTopicTag(tag2);
        String key = topic + "_" + tag;
        EventMessageProcessStatus strategy = map.get(key);
        if (strategy == null) {
            key = topic;
            strategy = map.get(key);
        }
        if (strategy == null) {
            key = "default";
            strategy = map.get(key);
        }
        return strategy;
    }


    private String getTopicTag(String tag2) {
        String tag;
        if (StringUtils.isBlank(tag2)) {
            tag = "";
        } else {
            tag = tag2;
        }
        return tag;
    }
}
